/**
 * API请求工具类
 * 封装HTTP请求功能，包含错误处理、认证、重试等
 */

class ApiClient {
    constructor(options = {}) {
        this.baseUrl = options.baseUrl || '';
        this.timeout = options.timeout || 30000;
        this.defaultHeaders = options.defaultHeaders || {
            'Content-Type': 'application/json'
        };
        this.retryCount = options.retryCount || 3;
        this.retryDelay = options.retryDelay || 1000;
        this.authManager = options.authManager || null;
    }

    /**
     * 获取完整的请求URL
     */
    getUrl(endpoint) {
        return `${this.baseUrl}${endpoint}`;
    }

    /**
     * 获取请求头（包含认证信息）
     */
    async getHeaders(customHeaders = {}) {
        const headers = { ...this.defaultHeaders, ...customHeaders };
        
        // 如果有认证管理器，获取认证头
        if (this.authManager) {
            const authHeader = await this.authManager.getAuthHeader();
            if (authHeader) {
                headers['Authorization'] = authHeader;
            }
        }
        
        return headers;
    }

    /**
     * 处理API响应
     */
    async handleResponse(response) {
        const contentType = response.headers.get('content-type');
        
        if (response.status === 204) {
            return { success: true, data: null };
        }

        let data;
        if (contentType && contentType.includes('application/json')) {
            data = await response.json();
        } else {
            data = await response.text();
        }

        if (response.ok) {
            return {
                success: true,
                data: data,
                status: response.status,
                headers: Object.fromEntries(response.headers.entries())
            };
        } else {
            // 处理认证错误
            if (response.status === 401) {
                if (this.authManager) {
                    await this.authManager.handleAuthError();
                }
            }

            throw new ApiError(
                data.message || `请求失败 (${response.status})`,
                response.status,
                data
            );
        }
    }

    /**
     * 处理请求错误
     */
    async handleError(error, endpoint, options) {
        // 如果是认证错误且需要重试
        if (error.status === 401 && this.authManager && options.retryAuth !== false) {
            try {
                // 尝试刷新token
                const refreshed = await this.authManager.refreshToken();
                if (refreshed) {
                    // 重新发起请求
                    return this.request(endpoint, { ...options, retryAuth: false });
                }
            } catch (refreshError) {
                console.error('Token refresh failed:', refreshError);
            }
        }

        // 网络错误或超时
        if (error.name === 'AbortError') {
            throw new ApiError('请求超时', 408);
        }

        if (error.name === 'NetworkError') {
            throw new ApiError('网络连接失败', 0);
        }

        // 重新抛出其他错误
        throw error;
    }

    /**
     * 延迟函数
     */
    delay(ms) {
        return new Promise(resolve => setTimeout(resolve, ms));
    }

    /**
     * 重试请求
     */
    async retryRequest(requestFn, retries = this.retryCount) {
        let lastError;
        
        for (let i = 0; i <= retries; i++) {
            try {
                return await requestFn();
            } catch (error) {
                lastError = error;
                
                // 如果是客户端错误（4xx），不重试
                if (error.status >= 400 && error.status < 500 && error.status !== 429) {
                    throw error;
                }
                
                // 如果是最后一次尝试，抛出错误
                if (i === retries) {
                    throw error;
                }
                
                // 等待后重试
                await this.delay(this.retryDelay * Math.pow(2, i));
            }
        }
        
        throw lastError;
    }

    /**
     * 发起HTTP请求
     */
    async request(endpoint, options = {}) {
        const {
            method = 'GET',
            headers = {},
            body = null,
            signal = null,
            timeout = this.timeout,
            noLoading = false,
            showError = true,
            retries = this.retryCount,
            ...fetchOptions
        } = options;

        const url = this.getUrl(endpoint);
        const requestHeaders = await this.getHeaders(headers);

        const fetchOptions = {
            method,
            headers: requestHeaders,
            signal: signal || AbortSignal.timeout(timeout),
            ...fetchOptions
        };

        if (body) {
            if (body instanceof FormData) {
                fetchOptions.body = body;
                delete fetchOptions.headers['Content-Type'];
            } else {
                fetchOptions.body = JSON.stringify(body);
            }
        }

        const requestFn = async () => {
            if (!noLoading) {
                window.uxUtils.showLoading(`api-${endpoint}-${method}`, `${method} ${endpoint}`);
            }

            try {
                const response = await fetch(url, fetchOptions);
                return await this.handleResponse(response);
            } catch (error) {
                await this.handleError(error, endpoint, options);
                throw error;
            } finally {
                if (!noLoading) {
                    window.uxUtils.hideLoading(`api-${endpoint}-${method}`);
                }
            }
        };

        try {
            if (retries > 0) {
                return await this.retryRequest(requestFn, retries);
            } else {
                return await requestFn();
            }
        } catch (error) {
            if (showError) {
                window.uxUtils.showError(error.message);
            }
            throw error;
        }
    }

    /**
     * GET请求
     */
    async get(endpoint, params = {}, options = {}) {
        const url = new URL(this.getUrl(endpoint));
        Object.keys(params).forEach(key => {
            if (params[key] !== undefined && params[key] !== null) {
                url.searchParams.append(key, params[key]);
            }
        });

        return this.request(url.pathname + url.search, { ...options, method: 'GET' });
    }

    /**
     * POST请求
     */
    async post(endpoint, data = {}, options = {}) {
        return this.request(endpoint, { ...options, method: 'POST', body: data });
    }

    /**
     * PUT请求
     */
    async put(endpoint, data = {}, options = {}) {
        return this.request(endpoint, { ...options, method: 'PUT', body: data });
    }

    /**
     * PATCH请求
     */
    async patch(endpoint, data = {}, options = {}) {
        return this.request(endpoint, { ...options, method: 'PATCH', body: data });
    }

    /**
     * DELETE请求
     */
    async delete(endpoint, options = {}) {
        return this.request(endpoint, { ...options, method: 'DELETE' });
    }

    /**
     * 上传文件
     */
    async upload(endpoint, file, options = {}) {
        const formData = new FormData();
        formData.append('file', file);
        
        // 添加额外字段
        if (options.fields) {
            Object.entries(options.fields).forEach(([key, value]) => {
                formData.append(key, value);
            });
        }

        // 显示上传进度
        let progressKey;
        if (!options.noLoading) {
            progressKey = `upload-${endpoint}-${file.name}`;
            window.uxUtils.showLoading(progressKey, `上传中: ${file.name}`);
        }

        try {
            const response = await this.request(endpoint, {
                ...options,
                method: 'POST',
                body: formData,
                noLoading: true
            });

            if (!options.noLoading) {
                window.uxUtils.hideLoading(progressKey);
                window.uxUtils.showSuccess('文件上传成功');
            }

            return response;
        } catch (error) {
            if (!options.noLoading) {
                window.uxUtils.hideLoading(progressKey);
            }
            throw error;
        }
    }

    /**
     * 批量请求
     */
    async batch(requests, options = {}) {
        const {
            concurrency = 3,
            stopOnError = true,
            showProgress = true
        } = options;

        if (showProgress) {
            window.uxUtils.showLoading('batch-requests', `批量处理中: 0/${requests.length}`);
        }

        const results = [];
        let completed = 0;
        let hasError = false;

        const processRequest = async (request, index) => {
            try {
                const result = await this.request(request.endpoint, {
                    ...request.options,
                    noLoading: true,
                    showError: false
                });
                
                results[index] = { success: true, data: result };
            } catch (error) {
                results[index] = { success: false, error: error.message };
                
                if (stopOnError) {
                    hasError = true;
                    throw error;
                }
            } finally {
                completed++;
                if (showProgress) {
                    window.uxUtils.updateLoadingMessage('batch-requests', `批量处理中: ${completed}/${requests.length}`);
                }
            }
        };

        try {
            // 分批处理请求
            const chunks = [];
            for (let i = 0; i < requests.length; i += concurrency) {
                chunks.push(requests.slice(i, i + concurrency));
            }

            for (const chunk of chunks) {
                if (hasError) break;
                await Promise.all(chunk.map((request, index) => 
                    processRequest(request, requests.indexOf(request))
                ));
            }

            if (showProgress) {
                window.uxUtils.hideLoading('batch-requests');
            }

            const successful = results.filter(r => r.success).length;
            const failed = results.filter(r => !r.success).length;

            if (failed > 0) {
                window.uxUtils.showWarning(`批量处理完成: ${successful}成功, ${failed}失败`);
            } else {
                window.uxUtils.showSuccess(`批量处理完成: ${successful}成功`);
            }

            return results;

        } catch (error) {
            if (showProgress) {
                window.uxUtils.hideLoading('batch-requests');
            }
            throw error;
        }
    }

    /**
     * WebSocket连接
     */
    createWebSocket(endpoint, options = {}) {
        const {
            onMessage = null,
            onError = null,
            onClose = null,
            onOpen = null,
            reconnect = true,
            maxReconnectAttempts = 5,
            reconnectDelay = 1000
        } = options;

        const url = this.baseUrl.startsWith('http') 
            ? this.baseUrl.replace('http', 'ws') + endpoint
            : endpoint;

        let ws;
        let reconnectAttempts = 0;
        let shouldReconnect = reconnect;

        const connect = () => {
            try {
                ws = new WebSocket(url);

                ws.onopen = (event) => {
                    console.log('WebSocket connected');
                    reconnectAttempts = 0;
                    if (onOpen) onOpen(event);
                };

                ws.onmessage = (event) => {
                    try {
                        const data = JSON.parse(event.data);
                        if (onMessage) onMessage(data, event);
                    } catch (error) {
                        console.error('WebSocket message parse error:', error);
                        if (onMessage) onMessage(event.data, event);
                    }
                };

                ws.onclose = (event) => {
                    console.log('WebSocket disconnected');
                    if (onClose) onClose(event);

                    if (shouldReconnect && reconnectAttempts < maxReconnectAttempts) {
                        reconnectAttempts++;
                        console.log(`Attempting to reconnect... (${reconnectAttempts}/${maxReconnectAttempts})`);
                        setTimeout(connect, reconnectDelay * Math.pow(2, reconnectAttempts - 1));
                    }
                };

                ws.onerror = (event) => {
                    console.error('WebSocket error:', event);
                    if (onError) onError(event);
                };

            } catch (error) {
                console.error('WebSocket connection error:', error);
                if (onError) onError(error);
            }
        };

        connect();

        return {
            send: (data) => {
                if (ws && ws.readyState === WebSocket.OPEN) {
                    ws.send(typeof data === 'string' ? data : JSON.stringify(data));
                } else {
                    console.warn('WebSocket is not connected');
                }
            },
            close: () => {
                shouldReconnect = false;
                if (ws) {
                    ws.close();
                }
            },
            getReadyState: () => ws ? ws.readyState : WebSocket.CLOSED
        };
    }
}

/**
 * API错误类
 */
class ApiError extends Error {
    constructor(message, status = 0, data = null) {
        super(message);
        this.name = 'ApiError';
        this.status = status;
        this.data = data;
    }
}

/**
 * 创建默认API客户端实例
 */
function createApiClient(options = {}) {
    // 从auth-manager获取认证管理器
    const authManager = window.authManager || null;
    
    return new ApiClient({
        baseUrl: window.API_BASE_URL || '/api',
        authManager,
        ...options
    });
}

// 创建全局默认实例
window.apiClient = createApiClient();

// 导出模块
if (typeof module !== 'undefined' && module.exports) {
    module.exports = { ApiClient, ApiError, createApiClient };
}